home *** CD-ROM | disk | FTP | other *** search
/ Network Support Library / RoseWare - Network Support Library.iso / apidev / ndr2.exe / PRTFILE.C < prev    next >
C/C++ Source or Header  |  1993-09-02  |  8KB  |  306 lines

  1. /****************************************************************************
  2. The following code was taken from the Network Developer's Resource, published
  3. by RoseWare.  All contents are Copyright (c) 1993, RoseWare.  All Rights
  4. Reserved.
  5.  
  6. This material is made available as a service for subscribers of the Network
  7. Developer's Resource.  This material is not public domain.  Simply put, if you
  8. are not a subscriber of the Network Developer's Resource, you are using this
  9. material illegally.  
  10.  
  11. Those interested in subscribing should contact RoseWare via:
  12.  
  13. CompuServe:    76711,110
  14. Internet:      76711.110@compuserve.com
  15. Phone:         (703) 799-2509
  16. Fax:           (703) 799-8041
  17. BBS:           (703) 799-2536
  18. US Mail:       P.O. Box 257
  19.            Mount Vernon, VA  22121-0257
  20.  
  21. Also see the file SUBSCRIB.TXT in this ZIP file...
  22.  
  23. Contents:
  24.  
  25. Excerpts from the Questions and Answers section in the September/October '93
  26. issue of the Network Developer's Resource.  See text for explanation of the 
  27. code.
  28.  
  29. ****************************************************************************/
  30.  
  31. // PrtFile -- Prints a file to a NetWare print queue
  32.  
  33. #include <stdio.h>
  34. #include <dos.h>
  35. #include <string.h>
  36. #include <fcntl.h>
  37. #include <io.h>
  38. #include <alloc.h>
  39. #include <stdlib.h>
  40.  
  41. typedef unsigned char BYTE;
  42. typedef unsigned int WORD;
  43. typedef unsigned long LONG;
  44.  
  45. #define QUEUE 0x0300
  46.  
  47. // MAX_BYTES is approximately what's left on the local heap to use as
  48. // a buffer for file i/o
  49. #define MAX_BYTES 63000
  50.  
  51. // Global types
  52. struct scanBindReq
  53. {
  54.     WORD    Length;
  55.     BYTE    Function;
  56.     LONG    LastObjectID;
  57.     WORD    ObjectType;
  58.     BYTE    ObjectNameLength;
  59.     BYTE    ObjectName[48];
  60. };
  61.  
  62. struct scanBindRep
  63. {
  64.     WORD    Length;
  65.     LONG    ObjectID;
  66.     WORD    ObjectType;
  67.     BYTE    ObjectName[48];
  68.     BYTE    ObjectFlag;
  69.     BYTE    ObjectSecurity;
  70.     BYTE    ObjectHasProperties;
  71. };
  72.  
  73. // Local Prototypes
  74. int ScanBinderyObject( struct scanBindReq *Request, struct scanBindRep *Reply );
  75. int CreateQueueJobAndFile( LONG QueueID, WORD *jobNumber );
  76. int CloseFileAndStartQueueJob( LONG QueueID, WORD jobNumber );
  77. LONG LongSwap( LONG num );
  78. int IntSwap( int num );
  79. void main( int argc, char *argv[] );
  80.  
  81. void main( int argc, char *argv[] )
  82. {
  83.     struct scanBindReq ScanBindRequest;
  84.     struct scanBindRep ScanBindReply;
  85.     int result, deviceHandle, fileHandle;
  86.     unsigned int bytesRead;
  87.     WORD jobNumber;
  88.     LONG QueueID;
  89.     char *buf;
  90.  
  91.     // Check command-line syntax
  92.     if ( argc < 3 )
  93.     {
  94.         printf("usage: PrtFile queueName fileName\n" );
  95.         exit( 1 );
  96.     }
  97.  
  98.     /* ------------------------------------------------------------- */
  99.     /*  Step 1:  Locate Queue and get it's object ID
  100.     /* ------------------------------------------------------------- */
  101.  
  102.     /* Initialize Request/Reply packets to 0 */
  103.     memset( &ScanBindRequest, NULL, sizeof( struct scanBindReq ) );
  104.     memset( &ScanBindReply, NULL, sizeof( struct scanBindRep ) );
  105.  
  106.     /* Setup for call to scan bindery for our queue */
  107.     ScanBindRequest.LastObjectID = 0xFFFFFFFFL;
  108.     ScanBindRequest.ObjectType = QUEUE;
  109.     strcpy( ScanBindRequest.ObjectName, strupr( argv[1] ) );
  110.         ScanBindRequest.ObjectNameLength = strlen( ScanBindRequest.ObjectName );
  111.  
  112.     result = ScanBinderyObject( &ScanBindRequest, &ScanBindReply );
  113.     if ( result == 0xFC )
  114.     {
  115.         printf( "Queue %s not found\n", argv[1] );
  116.         exit( 1 );
  117.     }
  118.     else
  119.     {
  120.         if ( result )
  121.         {
  122.             printf( "Error scanning for queue, result = %X\n", result );
  123.             exit( 1 );
  124.         }
  125.         else
  126.             QueueID = ScanBindReply.ObjectID;
  127.     }
  128.  
  129.     /* ------------------------------------------------------------- */
  130.     /*  Step 2: Place job into queue with CreateQueueJobAndFile,     */
  131.     /*           open the NETQ device and specified file and         */
  132.     /*           copy the file to NETQ, then close the device        */
  133.     /*           and file and call CloseFileAndStartQueueJob         */
  134.     /* ------------------------------------------------------------- */
  135.  
  136.     result = CreateQueueJobAndFile( QueueID, &jobNumber );
  137.     if ( result )
  138.     {
  139.         printf( "Error creating queue job and file, result = %X\n", result );
  140.         exit( 1 );
  141.     }
  142.  
  143.     // Open user-specified file
  144.     fileHandle = open( strupr( argv[2] ), O_RDONLY | O_BINARY );
  145.     if ( fileHandle == -1 )
  146.     {
  147.         printf( "Error opening file %s\n", argv[2] );
  148.         exit( 1 );
  149.     }
  150.  
  151.     // Open NETQ: device
  152.     deviceHandle = open( "NETQ", O_WRONLY | O_BINARY );
  153.     if ( deviceHandle == -1 )
  154.     {
  155.         printf( "Error opening device NETQ:\n" );
  156.         close( fileHandle );
  157.         exit( 1 );
  158.     }
  159.  
  160.     buf = (char *)malloc( MAX_BYTES );
  161.     bytesRead = MAX_BYTES;
  162.     while ( bytesRead == MAX_BYTES )
  163.     {
  164.         bytesRead = read( fileHandle, buf, MAX_BYTES );
  165.         write( deviceHandle, buf, bytesRead );
  166.     }
  167.     close( fileHandle );
  168.     close( deviceHandle );
  169.  
  170.     result = CloseFileAndStartQueueJob( QueueID, jobNumber );
  171.     if ( result )
  172.     {
  173.         printf( "Error closing queue job and file, result = %X\n", result );
  174.         exit( 1 );
  175.     }
  176. }
  177.  
  178. int ScanBinderyObject( struct scanBindReq *Request, struct scanBindRep *Reply )
  179. {
  180.     Request->Function = 0x37;
  181.     Request->Length = sizeof( struct scanBindReq ) - 2;
  182.     Reply->Length = sizeof( struct scanBindRep ) - 2;
  183.  
  184.     _SI = (unsigned)Request;
  185.     _DI = (unsigned)Reply;
  186.     _ES = _DS;
  187.     _AH = 0xE3;
  188.  
  189.     geninterrupt( 0x21 );
  190.  
  191.     return _AL;
  192. }
  193.  
  194. int CreateQueueJobAndFile( LONG QueueID, WORD *jobNumber )
  195. {
  196.     int result;
  197.  
  198.     struct createQueueJobReq
  199.     {
  200.         WORD    Length;
  201.         BYTE    Function;
  202.         LONG    QueueID;
  203.         BYTE    ClientStation;
  204.         BYTE    ClientTaskNumber;
  205.         LONG    ClientIDNumber;
  206.         LONG    TargetServerIDNumber;
  207.         BYTE    TargetExecutionTime[6];
  208.         BYTE    JobEntryTime[6];
  209.         WORD    JobNumber;
  210.         WORD    JobType;
  211.         BYTE    JobPosition;
  212.         BYTE    JobControlFlags;
  213.         BYTE    JobFileName[14];
  214.         BYTE    JobFileHandle[6];
  215.         BYTE    ServerStation;
  216.         BYTE    ServerTaskNumber;
  217.         LONG    ServerIDNumber;
  218.         BYTE    TextJobDescription[50];
  219.         BYTE    ClientRecordArea[152];
  220.     } Request;
  221.  
  222.     struct createQueueJobRep
  223.     {
  224.         WORD    Length;
  225.         BYTE    ClientStation;
  226.         BYTE    ClientTaskNumber;
  227.         LONG    ClientIDNumber;
  228.         LONG    TargetServerIDNumber;
  229.         BYTE    TargetExecutionTime[6];
  230.         BYTE    JobEntryTime[6];
  231.         WORD    JobNumber;
  232.         WORD    JobType;
  233.         BYTE    JobPosition;
  234.         BYTE    JobControlFlags;
  235.         BYTE    JobFileName[14];
  236.         BYTE    JobFileHandle[6];
  237.         BYTE    ServerStation;
  238.         BYTE    ServerTaskNumber;
  239.         LONG    ServerIDNumber;
  240.     } Reply;
  241.  
  242.     /* Initialize Request/Reply packets to 0 */
  243.     memset( &Request, NULL, sizeof( Request ) );
  244.     memset( &Reply, NULL, sizeof( Reply ) );
  245.  
  246.     Request.Length = sizeof( Request ) - 2;
  247.     Request.Function = 0x68; /* Monumental confusion, Novell manual says 6D */
  248.     Request.QueueID = QueueID;
  249.     Request.TargetServerIDNumber = 0xFFFFFFFF;
  250.     memset( Request.TargetExecutionTime, 0xFF, 6 );
  251.  
  252.     Reply.Length = sizeof( Reply ) - 2;
  253.  
  254.     _SI = (unsigned)&Request;
  255.     _DI = (unsigned)&Reply;
  256.     _ES = _DS;
  257.     _AH = 0xE3;
  258.  
  259.     geninterrupt( 0x21 );
  260.  
  261.     result = _AL;
  262.     *jobNumber = Reply.JobNumber;
  263.  
  264.     return result;
  265. }
  266.  
  267. int CloseFileAndStartQueueJob( LONG QueueID, WORD jobNumber )
  268. {
  269.     BYTE Request[9] = { 9, 0, 0x69, 0, 0, 0, 0, 0, 0 };
  270.     WORD Reply = 0;
  271.  
  272.     *( (LONG *) ( Request + 3 ) ) = QueueID;
  273.     *( (WORD *) ( Request + 7 ) ) = jobNumber;
  274.  
  275.     _SI = (unsigned)Request;
  276.     _DI = (unsigned)&Reply;
  277.     _ES = _DS;
  278.     _AH = 0xE3;
  279.  
  280.     geninterrupt( 0x21 );
  281.  
  282.     return _AL;
  283. }
  284. LONG LongSwap( LONG num )
  285. {
  286.     LONG temp;
  287.  
  288.     temp = ( num & 0xFF000000 ) >> 24;
  289.     temp += ( num & 0xFF0000 ) >> 8;
  290.     temp += ( num & 0xFF00 ) << 8;
  291.     temp += ( num & 0xFF ) << 24;
  292.  
  293.     return temp;
  294. }
  295.  
  296. int IntSwap( int num )
  297. {
  298.     int temp;
  299.  
  300.     temp = ( num & 0xFF00 ) >> 8;
  301.     temp += ( num & 0xFF ) << 8;
  302.  
  303.     return temp;
  304. }
  305.  
  306.